
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "hi_task.h"

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_i2c.h"
#include "iot_gpio.h"

#include "oled_ssd1306.h"
#include "hi_time.h"
#include "hx711.h"
#include "iot_log.h"


//struct  shopping_cart cart_msg={0};
//struct  shopping_cart interconnect_msg={0};
//Taurus_Msg taurus_msg={0};
extern Taurus_Msg rfid_msg_show;
float gap_value=430;
//char buffer[80];
void RFID_write(hi_u8 wr_data);

uint32_t abs(uint32_t a,uint32_t b)
{
    if(a<b) return b-a;
    else    return a-b;
}

void Oled_Clearline(uint8_t i)
{
    OledShowString(0, 2*i,"                 ", 1);  
}


uint32_t hx711_read(void)
{
    IotGpioValue input=1;
    uint8_t i;
    uint32_t value=0;
    IoTGpioSetOutputVal(SCK, 0);
    IoTGpioGetInputVal(DT, &input); 
    while(input)
    {
        IoTGpioGetInputVal(DT, &input); 
    }
    hi_udelay(2);
    for(i=0;i<24;i++)
    {
        IoTGpioSetOutputVal(SCK, 1);
        hi_udelay(2);               
        value=value<<1;
        IoTGpioSetOutputVal(SCK, 0);
        IoTGpioGetInputVal(DT, &input); 
        if(input)
        {
            value++;
        }
        hi_udelay(2);
    }
    IoTGpioSetOutputVal(SCK, 1);
    hi_udelay(2);
    value = value^0x800000;
    IoTGpioSetOutputVal(SCK, 0);
    return value;        
}

uint8_t  gap_deal(float standard,float weight_real)
{
    float   distance;   
    distance = weight_real - standard;
    while(1)
    {
        if(distance > 1)
        {
            gap_value = gap_value + 0.01;
        }
        if(distance < -1)
        {
            gap_value = gap_value - 0.01;
        }
        return 1;
    }
}

uint32_t weight_average(void)  //times平均
{
    uint8_t i=0;
    uint8_t times=2;
    uint32_t sum_value=0;
    uint32_t value_before,value_now=0;
    value_before=hx711_read();
    while(i<times)
    {   
        sum_value=0;
        for(i=0;i<times;i++)
        {   
            value_now=value_before;
            value_before=hx711_read();
            if(abs(value_now,value_before)<200)
                sum_value+=value_now;
            else
                break;
        }
    }
    return sum_value/times;
}

int weight_state;       //0：无变化 1：检测中 2：删除成功 3：添加成功 
extern int rfid_state;  //0：无变化 2：删除 3：添加
int rfid_flag;          //0：无变化 1：请求rfid检测 2：rfid已检测 3：待上传服务器
float commodity_weight;
uint16_t shopping_msg(float weight_now)
{
    static float weight_old = 0;
    float gap;
    uint8_t i,j;
    gap=weight_now - weight_old;
    weight_old = weight_now;
    if(gap > 4)
    {
        commodity_weight = (int)(gap*10)/10.0;
        rfid_flag = 1;      //请求rfid检测
        weight_state = 1; //检测中
    }
    else if(gap > -4)
    {
        if(rfid_flag == 2) //rfid已检测
        {         
            weight_state = rfid_state;
        }
    }
    else
    {
        rfid_flag = 3;     //待上传服务器
        weight_state = 0;
        rfid_state = 0;
    }
    return weight_state;
}

void oled_display(float weight_real)
{
    IotGpioValue input=1;
    int i;
    char buffer[80];
    IoTGpioGetInputVal(KEY1, &input); 
    if(input)
    {
        sprintf(buffer,"weight = %6.1fg",weight_real);
        OledShowString(0, 0,buffer, 1);
        sprintf(buffer,"number = %4d   ",rfid_msg_show.num);
        OledShowString(0, 2,buffer, 1);
        switch(shopping_msg(weight_real))
        {
            case 0: sprintf(buffer,"right weight   "); break;
            case 1: sprintf(buffer,"wait check     "); break;
            case 2: sprintf(buffer,"sub success    "); break;
            case 3: sprintf(buffer,"add success    "); break;//oled宽度16

        //default:printf("error\n"); break;
        }
        OledShowString(0, 4,buffer, 1);
        sprintf(buffer,"price = %.1f   ",rfid_msg_show.price); 
        OledShowString(0, 6,buffer, 1);
        printf("\nrfid_state = %d weight_state = %d\n",rfid_state,weight_state);
    }
    else
    {
        OledFillScreen(0);
        RFID_write(0);
        OledShowString(0, 2,"sub wr success", 1);    
    }
}

static void *weight_receive(char *param)
{
    float weight_real;
    float weight_base;
    OledFillScreen(0);
    weight_base =weight_average();
    while(1)
    {
        weight_real =weight_average();
        weight_real = (weight_real-weight_base)/gap_value;
        if(weight_real < 0.5)
            weight_real=0;
        oled_display(weight_real);
        hi_sleep(2000);
    }       
}


void Hx711_Demo(void)
{      
    osThreadAttr_t attr_weight;
    attr_weight.name = "hx711 Task";
    attr_weight.attr_bits = 0U;
    attr_weight.cb_mem = NULL;
    attr_weight.cb_size = 0U;
    attr_weight.stack_mem = NULL;
    attr_weight.stack_size = 4096; 
    attr_weight.priority = 22;
    OledInit();
    OledFillScreen(0);
    IoTI2cInit(AHT20_I2C_IDX, AHT20_BAUDRATE);//应该在前吗
    IoTGpioInit(DT);
    hi_io_set_func(DT,0);
    IoTGpioSetDir(DT,IOT_GPIO_DIR_IN);
    IoTGpioInit(SCK);
    hi_io_set_func(SCK,0);
    IoTGpioSetDir(SCK,IOT_GPIO_DIR_OUT);
    IoTGpioSetOutputVal(SCK,0);
    IoTGpioInit(KEY1);
    hi_io_set_func(KEY1,0);
    IoTGpioSetDir(KEY1,IOT_GPIO_DIR_IN);
    printf("[Hi711_Demo]  create OledmentTask!\n");
    if (osThreadNew(weight_receive, NULL, &attr_weight) == NULL) {
        printf("[Hi711_Demo] Falied to create OledmentTask!\n");
    }
}

SYS_RUN(Hx711_Demo);